krkr引擎研究记录
写在前面
入门
识别
最普遍的方式,查看文件属性
当安装完一个游戏之后,最简单的判断就是里面是否出现大量.xp3扩展名的文件如果只有一个data.xp3也算。
如果文件夹下没有.xp3文件,而是有其他的文件例如data.dat,此时可以通过查看这个文件的前3字节,xp3文件的前3字节是
58 50 33
,即unicode下的XP3
字符实例:syugaten/data.xp3
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 58 50 33 0D 0A 20 0A 1A 8B 67 01 17 00 00 00 00 XP3 媑
00000010 00 00 00 01 00 00 00 80 00 00 00 00 00 00 00 00 €
00000020 C3 65 9F 1F 00 00 00 00 89 50 4E 47 0A 1A 0A 00 胑? PNG
00000030 ......
xp3数据包其实可以打包进exe里,此时exe本身就可以看作xp3,而kirikiroid2能运行exe,其实指的是exe内嵌了xp3数据包,然后运行里面的脚本。遇到这种情况,右键exe属性,在详细信息里面可以看到TVP(KIRIKIRI) 2 core字样的话,那就可以确定了。
游戏入口的脚本默认在
data.xp3
包里,如果不存在这个包,那说明要么data包其实和exe捆绑了,要么就是exe被修改过,令其从其它包开始运行。其它的情况就算有也是极少数,而且往往已经深度改造过了。
插件与解密
游戏文件夹中存在一些dll,这些一般可以认为是插件,可以对照后面的KR2官方标准插件集来判断游戏是否使用了自定义插件。最后还附有Kirikiroid2已经实现了的插件集,可以对照判断Kirikiroid2对该游戏的支持程度。此外,并不是存在某个dll就说明游戏就一定会使用它,有时候开发者仅仅只是无脑复制了所有的插件到游戏目录中而已。
tpm扩展名的文件是在KR2运行时自动加载的插件,如果出现它,说明这个游戏极可能有经过加密,特别是这个tpm的名字与游戏名相同,或者叫dec、decode之类的。此外,如果文件名和官方插件列表中的插件一致的话,那也可能是作者懒得在脚本中加载插件,于是弄成tpm自动加载了。
官方插件中必带的有
wuvorbis
和krmovie
,前者提供ogg音频解码,后者提供视频回放支持。这两者的功能在Kirikiroid2中已经实现。dll插件其实可以打包进xp3包中,有时候看不到任何dll,不能说明这个游戏就没用插件。但至少可以说明它应该是没有加密的。如果需要测试它到底是否有加密的话,可以下载一个官方的krkr.exe,放到游戏目录中看能否运行即可。
结合之前xp3包可以打包进exe的情况,只有一个exe的游戏也可能用到了插件。而要判断它是否加密,同样用官方的krkr.exe,将游戏的exe拖到krkr.exe上,看能否运行即可。
附录
KIRIKIROID2支持的插件 | ||||
---|---|---|---|---|
wuvorbis | krmovie | extrans | csvParser | fstat |
getSample | layerExBTOA | layerExRaster | saveStruct | scriptsEx |
shrinkCopy | layerExImage(1.0.1起支持) |
KR2官方插件集 | ||||
---|---|---|---|---|
addFont | adjustMonitor | base64 | basetest | binaryStream |
clipboardEx | csvParser | dirlist | drawdevice | drawdeviceD3D |
drawdeviceIrrlicht | drawdeviceOgre | encode | exceptiontest | expat |
extrans | fftgraph | flashPlayer | fpslimit | fstat |
gameswf | getSample | htmlhelp | httprequest | httpserv |
imagesaver | javascript | json | KAGParserEx | layerEx |
layerExAgg | layerExAreaAverage | layerExAVI | layerExBTOA | layerExCairo |
layerExDraw | layerExGdiPlus | layerExImage | layerExLongExposure | layerExMovie |
layerExPerspective | layerExRaster | layerExSave | lineParser | magickpp |
memfile | messenger | minizip | mkpj | msgreceiver |
nativeclasstest | ncbind | parserskelton | process | qrcode |
registory | saveStruct | scriptsEx | shellExecute | shrinkCopy |
sigcheck | sqlite3 | sqlite3_xp3_vfs | squirrel | stdio |
systemEx | tftSave | varfile | videoEncoder | win32dialog |
win32ole | windowEx | windowExProgress | wmrdump | wsh |
wumsadp | wutcwf | wuvorbis | xmlhttprequest | xpressive |
实例
syugaten
| data.xp3 // 主要的数据包
| data.xp3.sig // *.sig文件是用来验证数据完整和防止篡改的,下同
| evimage.xp3 // cg数据包
| evimage.xp3.sig
| fgimage.xp3 // 立绘数据包
| fgimage.xp3.sig
| syugaten.exe // 主程序
| syugaten.exe.sig
| video.xp3 // 视频数据包
| video.xp3.sig
| voice.xp3 // 语音数据包
| voice.xp3.sig
|
| // 可能还会出现的有
| // patch*.xp3 补丁数据包
| // scenario.xp3 剧本数据包
| // bgimage.xp3 背景图数据包
| // *.cf 这个文件指定了存档目录
|
\---plugin // 插件文件夹
AlphaMovie.dll
AlphaMovie.dll.sig
extNagano.dll
extNagano.dll.sig
extrans.dll
extrans.dll.sig
getSample.dll
getSample.dll.sig
k2compat.dll
k2compat.dll.sig
kagexopt.dll
kagexopt.dll.sig
KAGParserEx.dll
KAGParserEx.dll.sig
krmovie.dll
krmovie.dll.sig
kztouch.dll
kztouch.dll.sig
layerExDraw.dll
layerExDraw.dll.sig
lzfs.dll
lzfs.dll.sig
menu.dll
menu.dll.sig
multiimage.dll
multiimage.dll.sig
PackinOne.dll
PackinOne.dll.sig
pkutil.dll
pkutil.dll.sig
psbfile.dll
psbfile.dll.sig
psd.dll
psd.dll.sig
textrender.dll
textrender.dll.sig
win32dialog.dll
win32dialog.dll.sig
win32ole.dll
win32ole.dll.sig
windowEx.dll
windowEx.dll.sig
wuopus.dll
wuopus.dll.sig
wuvorbis.dll
wuvorbis.dll.sig
资源加密
如果文件夹中含有.tpm文件,尤其是文件名和游戏名相同的情况下(不论位置,例如,插件可以存在于
plugin/
目录下或者游戏根目录
下),那么就要注意资源文件可能是被加密存储的对于这种情况要对资源进行解密才能提取出来,如果要进行资源重新打包,也要按照原来的加密方式进行打包,如果要以未加密方式打包就要移除加密插件并且解密所有的xp3文件
.tpm文件不一定就是加密插件
数据包内的脚本和文本文件可能会被二次加密,可以用下文提到的
KrkrTextDecryption
进行解密直接将解密出来的脚本文件打包不会影响游戏的正常运行
解包 / 打包
常用的解包工具有:
-
对于某些游戏无法解包的情况,可以尝试使用
0.0.0.5b
版本的KrkrExtract进行解包- KrkrTextDecryption 解密文本和脚本
FreeMoteToolkit 解密*.ks.csn格式的剧本文件
ScnEditorGUI 文本提取工具
运行流程
加载插件,加载.tpm文件进行解密
加载
data.xp3/startup.tjs
,这个脚本的唯一用途一般是调用data.xp3/system/Initialize.tjs
进行游戏初始化运行游戏
资源文件的加载优先级
一般来说,如果同时存在xp3文件,xp3文件同名文件夹,patch*.xp3,那么文件夹和patch的优先级要比原数据包优先级高
- 特别地,如果游戏不允许资源不打包运行,则不会使用
data/
文件夹的内容替换资源文件,详细查看此处
- 特别地,如果游戏不允许资源不打包运行,则不会使用
patch后数字越大优先级越高
例如,如果同时存在
data.xp3
,data/
文件夹,patch.xp3
,patch2.xp3
,那么patch2.xp3
的同名资源会覆盖掉patch.xp3
,data/
,data.xp3
中的同名资源并不是所有的游戏都允许不打包资源文件运行,修改方法请查看此处
编码转换
如果要在中文系统上运行日文原版游戏,那么需要把里面的脚本文件进行编码转换,避免崩溃和乱码问题
常见的需要转换编码的文件类型
.tjs
,.ks
,.scn
,.csv
,.txt
,.ini
,.func
,.asd
,.sinfo
,.stand
等一切文本类型的文件编码转换
原始文件通常是
Shift-JIS
编码,需要转换为UTF-16 LE
并且保留BOM头对于.scn文件,需要把.scn二次解包提取出剧本文件后转换编码,再打包回.scn
字体制作
让游戏正常显示中文以及绕过文件验证
附注
修改窗口标题
游戏窗口标题通常在Override.tjs
(位置应该是data.xp3/system/Override.tjs
)中的System.title
,或者全局搜索标题
xp3资源文件校验
xp3文件校验在scripts/release.tjs
中,或搜索data.xp3
立绘缺失问题
对于csv编码转换后立绘无法正常显示,可以在
Override.tjs
(位置应该是data.xp3/sysscn/Override.tjs
中第一行Plugins.link("csvParser.dll");
下添加以下代码with(global.CSVParser) {
.origParseStorage = .parseStorage;
.parseStorage = function (filename, utf8) {this.parse([].load(filename).join('\n'));}; //for utf-16 CSV
.initStorage = function (filename) {this.StorageBuffer = [].load(filename); this.StorageBuffer.reverse();};
.getNextLine = function () {
if (this.StorageBuffer!==void) {
var retData=this.StorageBuffer.pop();
if (retData!==void) return retData.split('\t');
}
};
};
对于因为资源包中路径是日文导致的立绘无法加载甚至游戏崩溃的情况,可以将
Initialize.tjs
中,将类似于Storages.addAutoPath("xxx") // 括号内为中文的路径
复制到
Config.tjs
的头部,重新打包运行即可
不封包运行
让游戏允许在data/
文件夹资源文件未打包的情况下运行
十六进制编辑游戏主程序,搜索forcedataxp3
,将括号内1
所对应的字节改为0
实例:syugaten.exe
修改前
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
002F09A0 ......
002F09B0 2D 2D 20 54 56 50 53 79 73 74 65 6D 53 65 63 75 -- TVPSystemSecu
002F09C0 72 69 74 79 4F 70 74 69 6F 6E 73 20 64 69 73 61 rityOptions disa
002F09D0 62 6C 65 6D 73 67 6D 61 70 28 31 29 3A 66 6F 72 blemsgmap(1):for
002F09E0 63 65 64 61 74 61 78 70 33 28 31 29 3A 61 63 63 cedataxp3(1):acc
002F09F0 65 70 74 66 69 6C 65 6E 61 6D 65 61 72 67 75 6D eptfilenameargum
002F0A00 ......
修改后
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
002F09A0 ......
002F09B0 2D 2D 20 54 56 50 53 79 73 74 65 6D 53 65 63 75 -- TVPSystemSecu
002F09C0 72 69 74 79 4F 70 74 69 6F 6E 73 20 64 69 73 61 rityOptions disa
002F09D0 62 6C 65 6D 73 67 6D 61 70 28 31 29 3A 66 6F 72 blemsgmap(1):for
002F09E0 63 65 64 61 74 61 78 70 33 28 30 29 3A 61 63 63 cedataxp3(0):acc
002F09F0 65 70 74 66 69 6C 65 6E 61 6D 65 61 72 67 75 6D eptfilenameargum
002F0A00 ......
可以看到,修改前后的区别就在002F09E0 + A
位置上的31
变成了30
,使程序中的forcedataxp3
参数由1
变成了0
从而实现了不打包资源也运行
其实建议顺带将disablemsgmap的参数也一并改成0,以防止奇奇怪怪的问题
修改存档路径
在游戏根目录下找到.cf文件,打开后将datapath内容删除或直接删除这一项配置即可
这一项配置的内容是用十六进制编码的,用来表示路径的字符串
如果这个文件不存在/这一项为空/根本不存在这个字段时,存档则放在/savedata/
下(默认路径)
所以理论上可以删除这个文件,使之把存档放在游戏目录下,但是如果游戏原本就存在这个文件的情况下,不建议删除这个文件
修改默认资源读取路径(仅krkr2)
其实这个方法理论上来说对于krkrz引擎也是适用的,只不过修改的字符串是unicode(一个字符两字节)编码的(krkr2是ascii码,一个字符一字节),需要把新文件名转换成unicode编码再修改,但是我没有修改成功,不知道为什么
krkrz下的例子
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
03081904 5C 00 00 00 2D 00 73 00 65 00 6C 00 00 00 00 00 \ - s e l
03081920 63 00 6F 00 6E 00 74 00 65 00 6E 00 74 00 2D 00 c o n t e n t -
03081936 64 00 61 00 74 00 61 00 00 00 00 00 5C 00 00 00 d a t a \
03081952 64 00 61 00 74 00 61 00 2E 00 78 00 70 00 33 00 d a t a . x p 3
03081968 00 00 00 00 64 00 61 00 74 00 61 00 2E 00 65 00 d a t a . e
03081984 78 00 65 00 00 00 00 00 64 00 61 00 74 00 61 00 x e d a t a
默认读取的文件夹是
data
,使用十六进制编辑器搜索exe中的content-data
,并将data
修改为想要的名称即可默认读取
data.xp3
,搜索并修改data.xp3
即可实例:lol2.exe
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
03104160 5C 00 2D 00 73 00 65 00 6C 00 00 00 63 6F 6E 74 \ - s e l cont
03104176 65 6E 74 2D 64 61 74 61 00 64 61 74 61 2E 78 70 ent-data data.xp
03104192 33 00 64 61 74 61 2E 65 78 65 00 41 62 6F 72 74 3 data.exe Abort
03104208 65 64 00 6B 72 64 65 76 75 69 2E 64 6C 6C 00 74 ed krdevui.dll t
修改前
修改后
引用其他封包下的资源文件
实现
如果要制作汉化补丁的话,把整个data解包->汉化文本->打包发布显然是不太现实的,因为一般来说,data.xp3的大小在1G以上,而我们需要汉化的部分只有文本和脚本、可能还会有少量的图片
这时我们可能会想到:能不能通过修改游戏默认加载资源文件的方式,让其默认加载我们制作的补丁文件,然后在补丁中引用原始data.xp3的资源文件达到复用资源的目的,减少补丁大小
打开一个已经制作好补丁的游戏看一下里面的实现
重点在于
Storages.addAutoPath(System.exePath+"data.xp3>");
Storages.addAutoPath(System.exePath+"data.xp3>bgimage/");
Storages.addAutoPath(System.exePath+"data.xp3>bgm/");
Storages.addAutoPath(System.exePath+"data.xp3>fgimage/");
Storages.addAutoPath(System.exePath+"data.xp3>image/");
Storages.addAutoPath(System.exePath+"data.xp3>others/");
Storages.addAutoPath(System.exePath+"data.xp3>rule/");
Storages.addAutoPath(System.exePath+"data.xp3>scenario/");
Storages.addAutoPath(System.exePath+"data.xp3>sound/");
Storages.addAutoPath(System.exePath+"data.xp3>system/");
这一段代码引用了原始的data.xp3下面的资源文件夹,达到了复用的目的
注意
所引用的资源不会包括子文件夹,如果要引用子文件夹中的资源需要单独列出
比如文件夹的结构为
data.xp3
| ....
\---bgimage
| | a.png
| | ....
| \--- a
| aa.png
| ab.png
| ....
\---fgimage
| ....
....
要引用bgimage下所有资源和bgimage/a文件夹下所有的文件时,要写成
Storages.addAutoPath(System.exePath+"data.xp3>bgimage/");
Storages.addAutoPath(System.exePath+"data.xp3>bgimage/a/");
所有文件夹的名字要以
\
结尾如果有某些图片资源要单独修改,直接把修改后的图片放在补丁文件夹根目录下打包即可
作者:子虚乌有
版权声明:本网站所有文章除特别声明外,均采用CC BY-NC-ND 4.0许可协议,转载请注明出处
注意:本网站所有文章内容仅供参考,如果您需解决具体问题(尤其法律、医学等领域),建议您详细咨询相关领域专业人士。
本文链接:http://peanutmelonseedbigalmond.pages.dev/2021/02/24/krkr%E5%BC%95%E6%93%8E%E7%A0%94%E7%A9%B6%E8%AE%B0%E5%BD%95/